using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Formboard
{
	public class CalculMove
	{
		public int moveResult;
		public int movx, movy;
		public int sequ;

		public CalculMove (CalculBoard goban, EnumCell color, int x, int y)
		{
			movx = x;
			movy = y;
			if (x > 0 && x < (goban.size - 1) && y > 0 && y < (goban.size - 1)) { // verifie if the cell is in goban
				if (goban.getCell (x, y).Value == EnumCell.Free) { // verifie if the cell is not occuped

					if (validate_move (color, goban.getCell (x, y))) {

						//browse the goban
						for (x = 0; x < goban.size; x++) {
							for (y = 0; y < goban.size; y++) {
								goban.getCell (x, y).check = false; // check stone to false
							}
						}
						moveResult = 0;
					} else {

						//browse the goban
						for (x = 0; x < goban.size; x++) {
							for (y = 0; y < goban.size; y++) {
								goban.getCell (x, y).check = false;  // check stone to false
							}
						}
						// unvalide move
						moveResult = 1;
					}
				} else {
					// Error already occuped
					moveResult = 1;
				}
			} else {
				//Error outside goban
				moveResult = 1;
			}
		}

		public static bool validate_move (EnumCell color, Cell myCell)
		{
			myCell.Value = color;
			// test if capture
			bool flag_capture = false;
			foreach (Cell aNeighbor in myCell.Neighbors) {
				if (aNeighbor.Value != color) {
					if (aNeighbor.Value != EnumCell.Free && aNeighbor.Value != EnumCell.Edge) {
						if (!freedom_chain (aNeighbor)) {
							if (capture (aNeighbor)) {
								flag_capture = true;
							}
						}
					}
				}
			}
			if (flag_capture == true) {
				return true;
			} else {
				foreach (Cell aNeighbor in myCell.Neighbors) {
					if (aNeighbor.Value == EnumCell.Free) {
						return true;
					}
					if (aNeighbor.Value == color) {
						if (freedom_chain (aNeighbor)) {
							return true;
						}
					}
				}
			}
			myCell.Value = EnumCell.Free;
			return false;
		}

		public static bool freedom_chain (Cell myCell)
		{
			Stack<Cell > pile = new Stack<Cell> ();
			EnumCell color = myCell.Value;
            

			foreach (Cell aNeighbor in myCell.Neighbors) {
				if (aNeighbor.check == false) {
					if (aNeighbor.Value == EnumCell.Free) {
						pile.Clear ();
						return true;
					} else {
						if (aNeighbor.Value == color) {
							myCell.check = true;
							pile.Push (aNeighbor);

						}

					}
				}
			}
			while (pile.Count != 0) {
				Cell CellNeighbor = pile.Pop ();

				foreach (Cell aNeighbor in CellNeighbor.Neighbors) {
					if (aNeighbor.check == false) {
						if (aNeighbor.Value == EnumCell.Free) {
							pile.Clear ();
							return true;
						} else {
                            
							if (aNeighbor.Value == color) {
								CellNeighbor.check = true;
								pile.Push (aNeighbor);

							}

						}
					}
				}
			}

			pile.Clear ();
			return false;
		}
        
		public static bool capture (Cell myCell)
		{
			Stack<Cell > pile = new Stack<Cell> ();
			EnumCell color = myCell.Value;

			foreach (Cell aNeighbor in myCell.Neighbors) {
				if (aNeighbor.Value == color) {
					pile.Push (aNeighbor);
				}
			}
			myCell.Value = EnumCell.Free;
			while (pile.Count != 0) {
				Cell CellNeighbor = pile.Pop ();
				CellNeighbor.Value = EnumCell.Free;
				foreach (Cell aNeighbor in CellNeighbor.Neighbors) {
					if (aNeighbor.Value == color) {
						pile.Push (aNeighbor);
					}
				}
			}
			return true;
		}
	}
}
